use crate::cluster::ManagedNode;
use crate::config::RaftConfig;
use crate::events::EventSystem;
use crate::network::NetworkManager;
use crate::raft_store::InMemStore;
use crate::storage::StorageManager;
use crate::{Error, NodeId, Result};

use openraft::{BasicNode, Config, Raft};
use serde::{Deserialize, Serialize};
use std::collections::BTreeMap;
use std::sync::Arc;
use tracing::{error, info};

/// Type configuration for OpenRaft
#[derive(Debug, Clone, Copy, Default, Serialize, Deserialize, PartialEq, Eq, PartialOrd, Ord)]
pub struct TypeConfig;

impl openraft::RaftTypeConfig for TypeConfig {
    type D = Request;
    type R = Response;
    type NodeId = NodeId;
    type Node = BasicNode;
    type Entry = openraft::Entry<TypeConfig>;
    type SnapshotData = std::io::Cursor<Vec<u8>>;
    type AsyncRuntime = openraft::TokioRuntime;
    type Responder = openraft::impls::OneshotResponder<TypeConfig>;
}

/// Request type for the state machine
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum Request {
    AddManagedNode { node: ManagedNode },
    RemoveManagedNode { node_id: String },
    UpdateNodeStatus { node_id: String, status: String },
    UpdateConfiguration { config: serde_json::Value },
}

/// Response type for the state machine
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum Response {
    Success,
    Error { message: String },
}

/// Snapshot data (placeholder not used yet)
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Snapshot {
    pub managed_nodes: Vec<ManagedNode>,
    pub configuration: serde_json::Value,
    pub last_applied_log: u64,
}

/// Raft manager that handles Raft consensus
pub struct RaftManager {
    node_id: NodeId,
    raft: Option<Raft<TypeConfig>>, // Optional until fully initialized
    storage: Arc<StorageManager>,
    network: Arc<NetworkManager>,
    event_system: Arc<EventSystem>,
    inmem_store: Arc<InMemStore>,
}

impl RaftManager {
    /// 获取当前节点 ID
    pub fn node_id(&self) -> NodeId {
        self.node_id
    }
    /// 创建 Raft 管理器（占位实现）
    ///
    /// 当前未真正初始化 OpenRaft 实例，仅保存依赖引用，便于后续补全。
    pub async fn new(
        node_id: NodeId,
        config: &RaftConfig,
        storage: Arc<StorageManager>,
        network: Arc<NetworkManager>,
        event_system: Arc<EventSystem>,
    ) -> Result<Self> {
        info!("Initializing Raft manager for node {}", node_id);

        // Create Raft configuration
        let _raft_config = Config {
            heartbeat_interval: config.heartbeat_interval_ms,
            election_timeout_min: config.election_timeout_ms,
            election_timeout_max: config.election_timeout_ms * 2,
            max_payload_entries: config.max_append_entries,
            ..Default::default()
        };

        Ok(Self {
            node_id,
            raft: None,
            storage,
            network,
            event_system,
            inmem_store: Arc::new(InMemStore::new(node_id)),
        })
    }

    /// 初始化新集群（引导）
    pub async fn initialize_cluster(&self) -> Result<()> {
        info!("Initializing Raft cluster with node {}", self.node_id);

        if let Some(raft) = &self.raft {
            let mut nodes = BTreeMap::new();
            nodes.insert(self.node_id, BasicNode::new(""));
            raft.initialize(nodes)
                .await
                .map_err(|e| Error::raft(format!("Failed to initialize cluster: {}", e)))?;
            self.event_system.emit_raft_leadership_change(true).await?;
        } else {
            info!("Raft not yet initialized (placeholder mode)");
        }

        Ok(())
    }

    /// 加入现有集群（连接 peers，等待被添加为 learner）
    pub async fn join_cluster(&self, peers: &[String]) -> Result<()> {
        info!("Joining Raft cluster with peers: {:?}", peers);

        // Connect to existing cluster members
        for peer in peers {
            if let Err(e) = self.network.connect_to_peer(peer).await {
                error!("Failed to connect to peer {}: {}", peer, e);
            }
        }

        // The actual joining process will be handled by the Raft protocol
        // when this node is added as a learner by the cluster leader

        Ok(())
    }

    /// 启动 Raft 相关后台逻辑（当前仅领导权监控）
    pub async fn start(&self) -> Result<()> {
        info!("Starting Raft manager");

        // Start leadership monitoring
        self.start_leadership_monitoring().await?;

        Ok(())
    }

    /// 关闭 Raft（若已初始化）
    pub async fn shutdown(&self) -> Result<()> {
        info!("Shutting down Raft manager");

        if let Some(raft) = &self.raft {
            raft.shutdown()
                .await
                .map_err(|e| Error::raft(format!("Failed to shutdown Raft: {}", e)))?;
        }

        Ok(())
    }

    /// 通过 Raft 添加受管节点（提交写请求）
    pub async fn add_managed_node(&self, node: ManagedNode) -> Result<()> {
        let request = Request::AddManagedNode { node };

        if let Some(raft) = &self.raft {
            let response = raft
                .client_write(request)
                .await
                .map_err(|e| Error::raft(format!("Failed to add managed node: {}", e)))?;
            match response.data {
                Response::Success => Ok(()),
                Response::Error { message } => Err(Error::raft(message)),
            }
        } else {
            if let Request::AddManagedNode { node } = request {
                self.inmem_store.add_managed(node);
            }
            Ok(())
        }
    }

    /// 通过 Raft 移除受管节点
    pub async fn remove_managed_node(&self, node_id: &str) -> Result<()> {
        let request = Request::RemoveManagedNode {
            node_id: node_id.to_string(),
        };

        if let Some(raft) = &self.raft {
            let response = raft
                .client_write(request)
                .await
                .map_err(|e| Error::raft(format!("Failed to remove managed node: {}", e)))?;
            match response.data {
                Response::Success => Ok(()),
                Response::Error { message } => Err(Error::raft(message)),
            }
        } else {
            if let Request::RemoveManagedNode { node_id } = request {
                self.inmem_store.remove_managed(&node_id);
            }
            Ok(())
        }
    }

    /// 列出受管节点（无 Raft 时返回内存存根数据）
    pub async fn list_managed_nodes(&self) -> Vec<ManagedNode> {
        if self.raft.is_some() {
            // TODO: extract from state machine once integrated
            self.inmem_store.get_managed()
        } else {
            self.inmem_store.get_managed()
        }
    }

    /// 判断当前节点是否为 leader
    pub async fn is_leader(&self) -> bool {
        if let Some(raft) = &self.raft {
            raft.metrics()
                .borrow()
                .current_leader
                .map(|leader| leader == self.node_id)
                .unwrap_or(false)
        } else {
            false
        }
    }

    /// 获取 Raft Metrics（序列化为 JSON；占位时返回 placeholder=true）
    pub async fn get_metrics(&self) -> Result<serde_json::Value> {
        if let Some(raft) = &self.raft {
            let metrics = raft.metrics().borrow().clone();
            serde_json::to_value(&metrics)
                .map_err(|e| Error::raft(format!("Failed to serialize metrics: {}", e)))
        } else {
            Ok(serde_json::json!({"placeholder": true}))
        }
    }

    /// 添加 learner 节点（非投票）
    pub async fn add_learner(&self, node_id: NodeId, node: BasicNode) -> Result<()> {
        if let Some(raft) = &self.raft {
            raft.add_learner(node_id, node, true)
                .await
                .map_err(|e| Error::raft(format!("Failed to add learner: {}", e)))?;
        }

        Ok(())
    }

    /// 变更集群成员（提交新 membership 配置）
    pub async fn change_membership(&self, members: BTreeMap<NodeId, BasicNode>) -> Result<()> {
        let member_ids: Vec<NodeId> = members.keys().cloned().collect();
        if let Some(raft) = &self.raft {
            raft.change_membership(member_ids, false)
                .await
                .map_err(|e| Error::raft(format!("Failed to change membership: {}", e)))?;
        }

        Ok(())
    }

    /// 触发快照生成
    pub async fn trigger_snapshot(&self) -> Result<()> {
        if let Some(raft) = &self.raft {
            raft.trigger()
                .snapshot()
                .await
                .map_err(|e| Error::raft(format!("Failed to trigger snapshot: {}", e)))?;
        }

        Ok(())
    }

    /// 启动领导权变化监控（定期轮询 metrics，比较 leader 变化并发事件）
    async fn start_leadership_monitoring(&self) -> Result<()> {
        let raft_opt = self.raft.clone();
        let event_system = self.event_system.clone();
        let node_id = self.node_id;

        tokio::spawn(async move {
            let mut last_leader: Option<NodeId> = None;
            let mut interval = tokio::time::interval(std::time::Duration::from_millis(100));

            while let Some(raft) = &raft_opt {
                interval.tick().await;

                let metrics = raft.metrics().borrow().clone();
                let current_leader = metrics.current_leader;

                if current_leader != last_leader {
                    let is_leader = current_leader == Some(node_id);

                    if let Err(e) = event_system.emit_raft_leadership_change(is_leader).await {
                        error!("Failed to emit leadership change event: {}", e);
                    }

                    last_leader = current_leader;
                }
            }
        });

        Ok(())
    }
}
